package com.dictionary.cn.core.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.dictionary.cn.core.DictionaryManager;
import com.dictionary.cn.core.DictionaryService;
import com.dictionary.cn.core.FilterProperty;
import com.dictionary.cn.core.TreeDictionaryService;
import com.dictionary.cn.core.dictionaryservice.config.DictionaryManagerBean;
import com.dictionary.cn.core.dictionaryservice.dcitionarybean.Dictionary;
import com.dictionary.cn.core.dictionaryservice.dcitionarybean.TreeDictionary;
import com.dictionary.cn.core.util.DictionarySpringContextUtils;


@Repository("dictionaryManager")
@DependsOn(value={"dictionarySpringContextUtils"})
public class DictionaryManagerImpl implements DictionaryManager {
	
    private static final Logger LOG = LoggerFactory.getLogger(DictionaryManagerImpl.class);

    /**
     * 默认的处理字典bean
     */
    private String defaultDictinaryServiceBean = "typeDictionaryService";
    
    /**
     * 默认的加载字典sql
     */
    private String defatulSql = "select type, beanId, param from dictionary_manager";
    
    
    private final FilterProperty<Dictionary> filterProperty = new FilterProperty<Dictionary>(){
        public boolean filter(Dictionary t) {
            return 0 == t.getDisabled();
        }};
    /**
     * 字典缓存
     * <type,DictionaryService>
     */
    private Map<String, DictionaryService<Dictionary>> cache = new HashMap<String, DictionaryService<Dictionary>>();
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    /**
     * <p>
     * 加载字典
     * </p>
     * @author xiaoruihu
     * @date 2015-6-1 上午11:20:35
     */
    @PostConstruct
    public void loadDictionaries(){
        LOG.info("---------------------loading all dictionaries start----------------------");
        List<DictionaryManagerBean> listDictionaryManagerBean = this.getAllDictionary();
        for(DictionaryManagerBean configBean : listDictionaryManagerBean){
           String  dictionaryService = configBean.getBeanId();
           if(StringUtils.isBlank(dictionaryService)){
               dictionaryService = this.defaultDictinaryServiceBean;
           }     
           
           DictionaryService<Dictionary> ds = DictionarySpringContextUtils.getBean(dictionaryService);
           
           if(ds == null){
               throw new RuntimeException("不存在的字典bean " + dictionaryService);
           }
           
           //加载单独的字典
           LOG.info("-------------------开始加载【" + configBean.getType() + "】字典------------------");
           try{
               ds.load(configBean.getType(), configBean.getParam());
           }catch(Exception e){
               LOG.error("----------------加载字典【"+configBean.getType()+"】失败！---------------", e);
               throw new RuntimeException("加载字典异常加载字典【"+configBean.getType()+"】失败！");
           }
           LOG.info("-------------------加载【" + configBean.getType() + "】字典结束------------------");
           this.cache.put(configBean.getType(), ds);
        }
        
        LOG.info("---------------------loading all dictionaries end-----------------------"); 
    }
    /**
     * 
     * <p>
     * 私有方法
     * </p>
     * @author xiaoruihu
     * @date 2015-6-1 下午12:30:29
     * @return
     */
    private List<DictionaryManagerBean> getAllDictionary(){
        return this.jdbcTemplate.query(this.defatulSql, BeanPropertyRowMapper.newInstance(DictionaryManagerBean.class));
    }
    
    public String getByKey(String type, Object key){
        Dictionary dic = this.getDicByKey(type, key);
        if(dic != null){
            return dic.getValue();
        }
        return null;
    }
    
    public String getByKey(String type, Object key,String defaultValue){
       String value = this.getByKey(type, key); 
       return value == null ? defaultValue : value; 
    }
    
    public Dictionary getDicByKey(String type, Object key){
        if(key == null){
            return null;
        }
        DictionaryService<Dictionary> ds = this.cache.get(type);
        if(ds != null){
            return ds.getDicByKey(key.toString());
        }
        return null;
    }
    
    public List<Dictionary> getAll(String type){
        return this.getAll(type, true);
    }
    
    public List<Dictionary> getAll(String type, boolean isDefaultFilter) {
        
        if(isDefaultFilter){
            return this.getAll(type, this.filterProperty);
        }else{
            return this.getAll(type, null);
        }
    }
    
    public List<TreeDictionary> getChildren(String type, Object parent) {
        return this.getChildren(type, parent, true);
    }
    
    public List<TreeDictionary> getChildren(String type, Object parent, boolean isDefaultFilter) {
        if(isDefaultFilter){
            return this.getChildren(type, parent, this.filterProperty);
        }else{
            return this.getChildren(type, parent, null);
        }
    }
    public List<Dictionary> getAll(String type, FilterProperty<Dictionary> filterProperty){
        
        List<Dictionary> result = null;
        DictionaryService<Dictionary> ds = this.cache.get(type);
        if(ds != null){
            result =  ds.getAll(filterProperty);
        }
        if(result == null){
            result = new ArrayList<Dictionary>();
        }
        return result;
    }

    /**
     * 获取子节点
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public List<TreeDictionary> getChildren(String type, Object parent,
            FilterProperty<Dictionary> filterProperty) {
        String temp = null;
        if(parent != null){
            temp = parent.toString();
        }
        List<TreeDictionary> result = null;
        DictionaryService<Dictionary> ds = this.cache.get(type);
        if(ds != null){
            if(ds instanceof TreeDictionaryService){
                result = ((TreeDictionaryService)ds).getChildren(temp, filterProperty);
            }else{
                throw new RuntimeException("该类型不是树形字典【" + type +"】------------");
            }
        }
        if(result == null){
            result = new ArrayList<TreeDictionary>();
        }
        return result;
    }
    
    /**
     * 
     * <p>
     * 刷新字典
     * </p>
     * @author xiaoruihu
     * @date 2015-5-28 下午03:33:21
     */
    public void flush(String type){
        DictionaryService<Dictionary> ds = this.cache.get(type);
        if(ds != null){
            ds.flush();
        } 
    }

}
